////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
//  File name:   Microphone.h
//  Version:     v1.00
//  Created:     30/11/2005 by Tomas.
//  Compilers:   Visual Studio.NET
//  Description: implementation of a Microphone class.
// -------------------------------------------------------------------------
//  History:
//
////////////////////////////////////////////////////////////////////////////

#include "StdAfx.h"

#ifdef SOUNDSYSTEM_USE_FMODEX400

#include "IAudioDevice.h"
#include "Microphone.h"
#include "SoundBuffer.h"
#include "Sound.h"
#include <FmodEx/inc/fmod.hpp>

//////////////////////////////////////////////////////////////////////////
// Initialization
//////////////////////////////////////////////////////////////////////////

CMicrophone::CMicrophone(IAudioDevice *pAudioDevice)
	: m_pAudioDevice(pAudioDevice),
		m_pBufMicro(NULL),
		m_DataSize(0),
		m_TempBufferSize(0)
{
}

//////////////////////////////////////////////////////////////////////////
CMicrophone::~CMicrophone()
{
	Stop();
}

//////////////////////////////////////////////////////////////////////////
void CMicrophone::Release()
{
	CryAutoLock<TMicroMutex> lock(m_Mutex);
	Stop();
}

//////////////////////////////////////////////////////////////////////////
void CMicrophone::Update()
{
	CryAutoLock<TMicroMutex> lock(m_Mutex);
	if(!m_pBufMicro)
	{
		m_DataSize=0;
		return;
	}
	if (m_pBufMicro)
	{
		m_pBufMicro->Update();
	}
}

//////////////////////////////////////////////////////////////////////////
bool CMicrophone::Stop()
{
	CryAutoLock<TMicroMutex> lock(m_Mutex);
	if (m_pBufMicro)
	{
		m_pBufMicro->UnloadData(sbUNLOAD_ALL_DATA);
		m_pBufMicro = NULL;
	}

	stl::free_container(m_anTempBuffer);
	m_TempBufferSize = 0;
	m_DataSize = 0;

	return true;
}

//////////////////////////////////////////////////////////////////////////
bool CMicrophone::Record(const unsigned int nRecordDevice, const unsigned int nBitsPerSample, 
					const unsigned int nSamplesPerSecond, const unsigned int nBufferSizeInSamples)
{
	CryAutoLock<TMicroMutex> lock(m_Mutex);
	SSoundBufferProps MicroProp = SSoundBufferProps("MicrophoneStream", 0, 0, btMICRO, 0, 0); 
	m_pBufMicro = m_pAudioDevice->CreateSoundBuffer(MicroProp);

	m_pBufMicro->GetInfo()->nBitsPerSample = nBitsPerSample;
	m_pBufMicro->GetInfo()->nBaseFreq = nSamplesPerSecond;
	m_pBufMicro->GetInfo()->nChannels = 1;
	m_pBufMicro->GetInfo()->nLengthInSamples = nBufferSizeInSamples;
	
	m_pBufMicro->LoadAsMicro(this);

	//allocate temporary buffer
	m_TempBufferSize = nBufferSizeInSamples;
	std::vector<uint8> anTemp(m_TempBufferSize, 0);
	m_anTempBuffer.swap(anTemp);

	return true;
}

////////////////////////////////////////////////////////////////////////////
int16* CMicrophone::GetData()
{
	if (!m_anTempBuffer.empty())
	{
		return (int16*)&m_anTempBuffer[0];
	}

	return NULL;
}

//////////////////////////////////////////////////////////////////////////
int CMicrophone::GetDataSize()
{
	return m_DataSize;
}

//////////////////////////////////////////////////////////////////////////
bool CMicrophone::ReadDataBuffer(const void* ptr1,const unsigned int len1,const void* ptr2,const unsigned int len2)
{
	CryAutoLock<TMicroMutex> lock(m_Mutex);

	int unsigned const anLength[2] = {len1, len2};
	void const* const apBuffers[2] = {ptr1, ptr2};

	m_DataSize = 0;

	for (int i = 0; i < 2; ++i)
	{
		int unsigned const nFreeSize = m_TempBufferSize - m_DataSize;
		int unsigned const nCopySize = min(anLength[i], nFreeSize);

		if (nCopySize > 0)
		{
			memcpy(&m_anTempBuffer[m_DataSize], apBuffers[i], nCopySize);
			m_DataSize += nCopySize;
		}
	}

	return true;
}

//////////////////////////////////////////////////////////////////////////
void CMicrophone::OnError(const char *error)
{
	//FIXME
}

#include UNIQUE_VIRTUAL_WRAPPER(IMicrophone)

#endif

